<?php

// +----------------------------------------------------------------------
// | WeMall Plugin for ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2022~2024 ThinkAdmin [ thinkadmin.top ]
// +----------------------------------------------------------------------
// | 官方网站: https://thinkadmin.top
// +----------------------------------------------------------------------
// | 免责声明 ( https://thinkadmin.top/disclaimer )
// | 会员免费 ( https://thinkadmin.top/vip-introduce )
// +----------------------------------------------------------------------
// | gitee 代码仓库：https://gitee.com/zoujingli/think-plugs-wemall
// | github 代码仓库：https://github.com/zoujingli/think-plugs-wemall
// +----------------------------------------------------------------------

declare (strict_types=1);

namespace plugin\mall\service;

use app\mall\model\MallOrder;
use app\mall\model\MallOrderItem;
use app\mall\model\MallOrderSender;
use app\mall\model\MallUserAddress;
use app\mall\service\ExpressService;
use app\mall\service\GoodsService;
use plugin\payment\model\PluginPaymentAddress;
use plugin\payment\model\PluginPaymentRecord;
use plugin\payment\service\Payment;
use plugin\wemall\model\PluginWemallConfigDiscount;
use plugin\wemall\model\PluginWemallOrder;
use plugin\wemall\model\PluginWemallOrderItem;
use plugin\wemall\model\PluginWemallOrderSender;
use plugin\wemall\model\PluginWemallUserCreate;
use plugin\wemall\model\PluginWemallUserRelation;
use think\admin\Exception;
use think\admin\Library;

/**
 * 商城订单数据服务
 * @class UserOrder
 * @package plugin\wemall\service
 */
abstract class UserOrder
{
    /**
     * 获取随减金额
     * @return float
     * @throws \think\admin\Exception
     */
    public static function reduct(): float
    {
        $config = sysdata('mall.config');
        if (empty($config['enable_reduct'])) return 0.00;
        $min = intval(($config['reduct_min'] ?? 0) * 100);
        $max = intval(($config['reduct_max'] ?? 0) * 100);
        return mt_rand($min, $max) / 100;
    }

    /**
     * 同步订单关联商品的库存
     * @param string $orderNo 订单编号
     * @return boolean
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function stock(string $orderNo): bool
    {
        $map = ['order_no' => $orderNo];
        $codes = MallOrderItem::mk()->where($map)->column('gcode');
        foreach (array_unique($codes) as $code) GoodsService::stock($code);
        return true;
    }

    /**
     * 获取订单模型
     * @param PluginWemallOrder|string $order
     * @param ?integer $unid 动态绑定变量
     * @param ?string $orderNo 动态绑定变量
     * @return \plugin\wemall\model\PluginWemallOrder
     * @throws \think\admin\Exception
     */
    public static function widthOrder($order, ?int &$unid = 0, ?string &$orderNo = ''): MallOrder
    {
        if (is_string($order)) {
            $order = MallOrder::mk()->where(['order_no' => $order])->findOrEmpty();
        }
        if ($order instanceof MallOrder) {
            [$unid, $orderNo] = [intval($order->getAttr('unid')), $order->getAttr('order_no')];
            return $order;
        }
        throw new Exception("无效订单对象！");
    }


      /**
     * 更新订单收货地址
     * @param \plugin\wemall\model\PluginWemallOrder $order
     * @param \plugin\payment\model\PluginPaymentAddress $address
     * @return boolean
     * @throws \think\admin\Exception
     */
    public static function perfect(MallOrder $order, MallUserAddress $address): bool
    {
        $unid = $order->getAttr('unid');
        $orderNo = $order->getAttr('order_no');
        // 根据地址计算运费
        $map1 = ['order_no' => $orderNo, 'status' => 1, 'deleted' => 0];
        $map2 = ['order_no' => $order->getAttr('order_no'), 'unid' => $unid];
        [$amount, $tCount, $tCode, $remark] = ExpressService::amount(
            MallOrderItem::mk()->where($map1)->column('delivery_code'),
            $address->getAttr('region_prov'), $address->getAttr('region_city'),
            (int)MallOrderItem::mk()->where($map2)->sum('delivery_count')
        );
        // 创建订单发货信息
        $data = [
            'delivery_code'   => $tCode, 'delivery_count' => $tCount, 'unid' => $unid,
            'delivery_remark' => $remark, 'delivery_amount' => $amount, 'status' => 1,
        ];
        $data['order_no'] = $orderNo;
        $data['address_id'] = $address->getAttr('id');
        // 收货人信息
        $data['user_name'] = $address->getAttr('user_name');
        $data['user_phone'] = $address->getAttr('user_phone');
        $data['user_idcode'] = $address->getAttr('idcode');
        $data['user_idimg1'] = $address->getAttr('idimg1');
        $data['user_idimg2'] = $address->getAttr('idimg2');
        // 收货地址信息
        $data['region_prov'] = $address->getAttr('region_prov');
        $data['region_city'] = $address->getAttr('region_city');
        $data['region_area'] = $address->getAttr('region_area');
        $data['region_addr'] = $address->getAttr('region_addr');
        // 记录原地址信息
        $data['extra'] = $data;
        MallOrderSender::mk()->where(['order_no' => $orderNo])->findOrEmpty()->save($data);
        // 组装更新订单数据, 重新计算订单金额
        $update = ['status' => 2, 'amount_express' => $data['delivery_amount']];
        $update['amount_real'] = round($order->getAttr('amount_discount') + $amount - $order->getAttr('amount_reduct'), 2);
        $update['amount_total'] = round($order->getAttr('amount_goods') + $amount, 2);
        // 支付金额不能少于零
        if ($update['amount_real'] <= 0) $update['amount_real'] = 0.00;
        if ($update['amount_total'] <= 0) $update['amount_total'] = 0.00;
        // 更新用户订单数据
        if ($order->save($update)) {
            // 触发订单确认事件
            Library::$sapp->event->trigger('PluginWemallOrderPerfect', $order);
            // 返回处理成功数据
            return true;
        } else {
            return false;
        }
    }

 
}